////////////////////////////////////////////////////////
//   File Name	:	"Timer.h"
//
//   Author		:	Ramon Johannessen (RJ)
//
//   Purpose	:	To provide an easy way to mark and use the passing of time
////////////////////////////////////////////////////////

#ifndef TIMER_H
#define TIMER_H

//////////////////////////////////////////////////////////////////////////
////////////////////////// CTimerBase ////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

class CTimerBase
{
	friend class CTimer;
	friend class CTriggerTimer;

	LARGE_INTEGER m_liCounterFreq;
	LARGE_INTEGER m_liLastCount;
	double m_dTotalTime;
	double m_dFPS;
	double m_dFPSElapsed;
	int	   m_nFrame;

	CTimerBase();
	void UpdateBase(double dElapsed);

public:
	inline void ResetElapsed() { m_dTotalTime = 0.0; }

	//////////////////////////////////////////////////////////////////////////
	//	ACCESSORS
	//////////////////////////////////////////////////////////////////////////
	inline double GetElapsed() const {return m_dTotalTime;} // elapsed is in seconds
	double GetTick() const;
	inline double GetFPS() const {return m_dFPS;}
};

//////////////////////////////////////////////////////////////////////////
////////////////////////// CTriggerTimer /////////////////////////////////
//////////////////////////////////////////////////////////////////////////

class CTriggerTimer : public CTimerBase
{
	bool   m_bIsOn;
	bool   m_bAutoUpdate;
	double m_dEndTime;
	double m_dPauseDur;
	double m_dPauseTimer;
public:

	// CTOR
	// if autoUpdate, this class keeps track of time passage internally
	// if startTimer, the Update function will accumulate time
	// if you want Update to trigger at a specific end time, pass in an end time here,
	//		also may be set in StartTimer() or SetEndTime()
	CTriggerTimer( bool autoUpdate = true, bool startTimer = false, double dEndTime = 0.0f);

	bool Update(double dElapsedTime = 0.0);

	void ResetTimer(bool bStop = true);
	//////////////////////////////////////////////////////////////////////////
	// does not update the timer for a specified amount of time
	inline void PauseTimer(double pauseDuration = 0.0) {m_bIsOn = false;}

	//////////////////////////////////////////////////////////////////////////
	// if you pass in an endtime, the update will return true when that endtime is reached
	void StartTimer(double endTime = 0.0, bool reset = true);

	//////////////////////////////////////////////////////////////////////////
	//	ACCESSORS
	inline bool  IsTimerRunning() const  {return m_bIsOn;}

	//////////////////////////////////////////////////////////////////////////
	//	MUTATORS
	inline void  SetEndTime(double dEndTime) {m_dEndTime = dEndTime;}
};

//////////////////////////////////////////////////////////////////////////
////////////////////////// CTimer ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

class CTimer : public CTimerBase
{

public:

	// DEFAULT CTOR
	// a simple timer to get the time step
	CTimer();

	//////////////////////////////////////////////////////////////////////////
	// FUNCTION:	Update()
	//	
	// RETURNS:		double - the time step since last update
	//////////////////////////////////////////////////////////////////////////
	double Update();

	//////////////////////////////////////////////////////////////////////////
	//	ACCESSORS
	
	//////////////////////////////////////////////////////////////////////////
	//	MUTATORS

};

#endif